package ai.mspbots.poc.controller.v1;

import ai.mspbots.poc.constants.ElasticSearchConstants;
import ai.mspbots.poc.core.Response;
import ai.mspbots.poc.es.entity.Document;
import ai.mspbots.poc.es.processor.MapperProcessor;
import ai.mspbots.poc.es.service.SearchService;
import ai.mspbots.poc.es.service.VectorService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("/v1/es/search")
public class ESSearchController {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private SearchService searchService;

    public static final int NINE = 9;
    public static final int TEN = 10;

    /**
     *  输入框自动补全提示功能（ElasticSearch使用completion实现补全功能）
     * @param request request
     * @param suggestValue 输入参数
     * @author liudz
     * @date 2021/4/19
     * @return 执行结果
     **/
    @GetMapping(value = "/completion")
    public Response<Object> getSuggestCompletion(@RequestParam String suggestValue, HttpServletRequest request) {
        log.info("--getSearchSuggest--begin--");
        // Long userId = Long.valueOf(request.getUserPrincipal().getName());
        //指定在哪个字段搜索
        String suggestField = "name.suggest";

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //suggestField为指定在哪个字段搜索，suggestValue为输入内容，TEN为10，代表输出显示最大条数
        CompletionSuggestionBuilder suggestionBuilderDistrict =
                new CompletionSuggestionBuilder(suggestField).prefix(suggestValue).size(TEN);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("name-suggest", suggestionBuilderDistrict);
        searchSourceBuilder.suggest(suggestBuilder);
        String esIndex = ElasticSearchConstants.INDEX_NAME;
        SearchRequest searchRequest = new SearchRequest(esIndex);
        // searchRequest.types("");
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            response = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("IOException:{}", e);
            return Response.error("查询错误", e.getMessage());
        }
        Suggest suggest = response.getSuggest();

        List<String> keywords = null;
        if (suggest != null) {
            keywords = new ArrayList<>();
            List<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> entries =
                    suggest.getSuggestion("name-suggest").getEntries();
            for (Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option> entry: entries) {
                for (Suggest.Suggestion.Entry.Option option: entry.getOptions()) {
                    String keyword = option.getText().string();
                    if (!StringUtils.isEmpty(keyword)) {
                        if (keywords.contains(keyword)) {
                            continue;
                        }
                        keywords.add(keyword);
                        if (keywords.size() >= NINE) {
                            break;
                        }
                    }
                }
            }
        }
        return Response.success(keywords);
    }

    @GetMapping("/search")
    public Response<List<Document>> search(@RequestParam String term) {
        String esIndex = ElasticSearchConstants.INDEX_NAME;
        String field = "name";
        String mapperProcessResult = MapperProcessor.processInput(term);
        List<Document> documents = searchService.fuzzySearch(esIndex, field, mapperProcessResult);
        return Response.success(documents);
    }

    @Autowired
    private VectorService vectorService;
    @GetMapping("/search/vector")
    public Response<List<Document>> vectorSearch(@RequestParam String term) {
        String mapperProcessResult = MapperProcessor.processInput(term);
        // String esIndex = ElasticSearchConstants.INDEX_NAME;
        // String field = "name";
        // String mapperProcessResult = MapperProcessor.processInput(term);
        // List<Document> documents = searchService.fuzzySearch(esIndex, field, mapperProcessResult);
        // return Response.success(documents);
        try {
            return Response.success(vectorService.search(mapperProcessResult));
        } catch (IOException e) {
            log.error("向量查询失败: {}", e.getMessage(), e);
            return Response.error("向量查询失败", new ArrayList<>());
        }
    }
}